library(CHNOSZ)
data(thermo)
library(xts)
library(dplyr)
library(dygraphs)
library(purrr)
library(ggplot2)
library(lubridate)
library(readr)
library(data.table)
library(forcats)
Calculate a time series of \(k\) in \(\frac{cm}{hr}\) using inputs: water temperature, water depth, wind speed. \(k\) is calculated using equation 2 in Poindexter et al. 2016, which uses a different formulation for wind-driven vs. thermal convection driven gas exchange based on thresholds for heat flux.
Background
Gas flux equation
\(Flux = k(C_{eq} - C_w)\)
\(k\) is typically reported as \(k_{600}\) to facilitate comparison.
\(k_{600} = k(\frac{600}{Sc})^{-n}\)
\(n\) is a factor characterizing the kinematic behavior of the water surface.
Previous studies
The most relevant studies on calculating gas exchange are:
- Read et al. 2012
- Holgerson et al 2017
- MacIntyre et al. 2010 - model \(k\) with two functions of \(U_{10}\), one for periods of surface heat loss and one for periods of heat gain
- Soloviev et al. 2007 - combined effects of surface heat loss and wind via surface dissipation of turbulent kinetic energy (from combined effects of buoyancy, wind shear, wave breaking)
- Poindexter and Variano 2013 - develop an analytical relationship between surface heat flux \(q\) and \(k\) (based on laboratory measurements)
- Poindexter et al. 2016
Poindexter and Variano (2013) developed new models for wetlands with emergent vegetation, based on the idea that emergent vegetation would attenuate wind speed above the water surface, modify fluid shear at the water surface, and influence stirring beneath the water surface. They focus on thermal convection, parameterized from surface heat loss, and wind shear, parameterized using the mean wind speed in the constant-velocity or shear-free region of the vegetation canopy.
Forested wetlands like Delmarva bays can be inundated areas without emergent vegetation (e.g. forested ponds), where tree canopy attenuates wind speed but effects of plant stems are not as relevant.
Using Poindexter et al 2016 method for wetland perspective, where emergent vegetation and surfactants are important. New relationships for \(k\) designed specifically for use in the presence of an emergent vegetation canopy. Based on lab measurements with a model wetland, which suggested a quadratic relationship between \(k\) and the mean in-canopy wind speed (Poindexter and Variano, 2013).
\(k\) is wind-driven when \(q \geq 0\) or \(Ra < 8 \times 10^6\), and thermal convection driven when \(q < 0\) and \(Ra > 8 \times 10^6\). \(Ra\) is the Rayleigh number, a function of heat flux. When \(Ra\) is below a critical value for a fluid, then heat transfer is primarily in the form of conduction; when it exceeds that value then heat transfer is primarily in the form of convection. *Except if water temperature is below 4 deg C, then \(\beta\) changes sign and \(k\) is thermally driven by \(q > 0\).
- First check if \(q\geq 0\), if yes, use \(k_{wind}\) unless water temp < 4.
- If \(q < 0\), use \(k_{thermal}\) unless \(Ra < 8\times 10^6\).
Surface Heat Flux
Surface heat flux \((q)\) can be used to estimate thermal convection. Negative heat fluxes indicate a cooling water column (water losing heat to the air) and positive heat flux means the water column is warming. Typical values of \(q\) in temperate wetlands are -200 to 300 W m^-2. Convective mixing occurs when the water is losing heat to the air \((q < 0)\).
\(q = \frac{dT_b}{dt}\rho c_pH\)
- \(c_p\) is the isobaric heat capacity (isobaric = constant pressure), in \(\frac{J}{kgK}\)
- \(\rho\) is water density, in \(\frac{kg}{m^3}\)
- \(H\) is the depth of the water column, in meters
- \(T_b\) is the bulk water temperature
Calculate \(q\), using functions from the CHNOSZ package to calculate water density and isobaric heat capacity
calc_q_heatflux <- function(temp_C, waterdepth_m, dT, dt_sec = 3600){
# isobaric heat capacity cal K^-1 mol^-1
cp = as.numeric(
CHNOSZ::water("Cp", T = 273.15 + temp_C))
# water density kg m^-3
rho = as.numeric(
CHNOSZ::water("rho", T = 273.15 + temp_C))
# convert cp to J kg^-1 K^-1
cp = cp*(4.184/0.018)
q_wm2 <- (dT/dt_sec) * rho * cp * waterdepth_m
return(q_wm2)
}
Rayleigh Number calculation
Used in combination with \(q\) to determine which formula to use for calculation of \(k\).
\(Ra = 4.7(\frac{-qg\beta L^4}{\alpha^2vc_p\rho})^{\frac{3}{4}}\)
- \(g\) - acceleration due to gravity
- \(q\) - water column heat flux
- \(L\) - characteristic length scale, wetland depth
Poindexter and Variano (2013) find that using the wetland depth as the length scale \(L\), the Rayleigh number threshold is met for wetland water columns deeper than 10cm for typical heat loss rates.
- \(\beta\) - thermal expansion coefficient
- \(\alpha\) - thermal diffusivity
- \(v\) - kinematic viscosity
- \(c_p\) - heat capacity at constant pressure
- \(\rho\) - density
calc_rayleigh <- function(q, temp_C = 25, lscale = 1){
g = -9.8 # m s^-2
beta = as.numeric(
CHNOSZ::water("alpha", T = 273.15 + temp_C)) # K^-1
alpha = as.numeric(
CHNOSZ::water("tdiff", T = 273.15 + temp_C)) #cm^2 s^-1
kv = as.numeric(
CHNOSZ::water("visck", T = 273.15 + temp_C)) #cm^2 s^-1
cp = as.numeric(
CHNOSZ::water("Cp", T = 273.15 + temp_C))
rho = as.numeric(
CHNOSZ::water("rho", T = 273.15 + temp_C)) # kg m^-3
# convert cm to m
alpha = alpha/10000
kv = kv/10000
ra <- 4.7*((-q*g*beta*lscale^4)/
(alpha^2*kv*cp*rho))^(3/4)
return(ra)
}
calc_rayleigh(q = .1, temp_C = 30, lscale = .10)
[1] 4532289
calc_rayleigh(q = .10, temp_C = 30, lscale = .10) > 8e6
[1] FALSE
Thermal convection K
From Poindexter et al. 2016 (GRL), a semi-emprical function derived from the relationship between heat flux and thermal convection, which is similar to the surface renewal models used for periods of relative calm in lakes and oceans by Read et al. 2012 and Soloviev et al. 2007.
\(k = 0.14^{\frac{3}{4}}(\frac{-qg\beta\alpha^2}{vc_p\rho})^{\frac{1}{4}}(\frac{Sc}{Pr})^{-n}\)
- \(q\) - water column heat flux, calculated from rate of change in wetland water column temperature with time (described in supporting info)
- \(g\) - acceleration due to gravity
- \(Sc\) - Schmidt number
Functions of water temperature and atmospheric pressure:
- \(\beta\) - thermal expansion coefficient
- \(\alpha\) - thermal diffusivity
- \(v\) - kinematic viscosity
- \(c_p\) - heat capacity at constant pressure
- \(\rho\) - density
- \(Pr\) - Prandtl number
Calculate k for thermal convection
calc_k_poindexter2b <- function(q, temp_C, n_surface = (2/3)){
# if(q < 0){stop("Negative heat flux.
# Please use wind model to calculate K.")}
g = 9.8 # m s^-2
beta = as.numeric(
CHNOSZ::water("alpha", T = 273.15 + temp_C)) # K^-1
alpha = as.numeric(
CHNOSZ::water("tdiff", T = 273.15 + temp_C)) #cm^2 s^-1
kv = as.numeric(
CHNOSZ::water("visck", T = 273.15 + temp_C)) #cm^2 s^-1
cp = as.numeric(
CHNOSZ::water("Cp", T = 273.15 + temp_C))
rho = as.numeric(
CHNOSZ::water("rho", T = 273.15 + temp_C)) # kg m^-3
Pr = as.numeric(
CHNOSZ::water("Prndtl", T = 273.15 + temp_C))
Sc = 600
# convert cp to J kg^-1 K^-1
cp = cp*(4.184/0.018)
# convert cm to m
alpha = alpha/10000
kv = kv/10000
k = (0.14^(3/4)) *
((-q * g * beta * alpha^2)/(kv * cp * rho))^(1/4) *
(Sc/Pr)^(-n_surface)
k_cmhr = k*100*3600
return(k_cmhr)
}
calc_k_poindexter2b(q = 50, temp_C = 25) # cm/hr
[1] NaN
calc_k_poindexter2b(q = -50, temp_C = 25) # cm/hr
[1] 0.636363
Wind-driven k
\(k = 3\Gamma{\langle U_{canopy}}\rangle^2 (\frac{Sc}{600})^{-n}\)
- \(\Gamma\) enhancement factor to account for fluctuations that increase the gas transfer velocity relative to value predicted from mean wind speed alone. Poindexter et al. use \(\Gamma = 0.32\) based on in-canopy wind speed measurements at their marsh study site. (Poindexter and Variano use 1.3 though?)
- \(U_{canopy}\) is mean in-canopy wind speed, which can be computed from wind shear stress and wind speed measured above the canopy (but is being monitored at sites QB and ND)
Calculate k for wind driven turbulence.
calc_k_poindexter2a <- function(ws, gamma = (1/3), Sc = 600, n_surface = (2/3)){
k = 3*gamma*(ws)^2 * (Sc/600)^(-n_surface)
return(k)
}
In-canopy wind speed is assumed to be in the zone where wind speed profile is vertical?
Data
Load data to use the equations above for calculating \(k\). Aggregate high resolution data to hourly means.
Temperature
Water temperature measured at 3 locations in a vertical profile, in 2 wetlands. Need to compare with water level to determine when sensors were in the water and when they were exposed (also evident by looking at daily fluctuations).
Look at typical daily time series pattern of temperature in the water column, to determine how to calculate \(\frac{dT}{dt}\). Poindexter and Variano use linear regression of temperature readings during their experiments.
temp_df <- read_csv("data/watertemp_qbMID.csv")
Parsed with column specification:
cols(
datetime = col_datetime(format = ""),
temp_C = col_double()
)
Wind
In-canopy wind speed measured with sonic anemometers approximately 1m over the water surface (varies between xx and xx due to changes in water level).
wind_df <- read_csv("data/windspeed_qb.csv")
Parsed with column specification:
cols(
datetime = col_datetime(format = ""),
ws_ms = col_double()
)
wind_df %>%
mutate(date = lubridate::date(datetime)) %>%
mutate(time_hr = lubridate::hour(datetime)) %>%
# filter(date >= as.Date('2018-06-01') & date <= as.Date('2018-07-01')) %>%
ggplot(aes(x = time_hr, y = ws_ms, group = date)) +
geom_line(aes(col = date)) +
# facet_wrap(~ lubridate::month(date)) +
# facet_wrap(~ lubridate::yday(date)) +
# facet_wrap(~ lubridate::wday(date, TRUE)) +
xlim(c(0, 24)) +
theme_bw()

wind-driven k is just a function of wind speed
wind_df <- wind_df %>%
mutate(k_wind = map_dbl(ws_ms, ~calc_k_poindexter2a(ws = .x)))
wind_df %>%
mutate(date = lubridate::date(datetime)) %>%
mutate(time_hr = lubridate::hour(datetime)) %>%
# filter(date >= as.Date('2018-06-01') & date <= as.Date('2018-07-01')) %>%
ggplot(aes(x = time_hr, y = k_wind, group = date)) +
geom_line(aes(col = date)) +
# facet_wrap(~ lubridate::month(date)) +
# facet_wrap(~ lubridate::yday(date)) +
# facet_wrap(~ lubridate::wday(date, TRUE)) +
xlim(c(0, 24)) +
theme_bw()

wind_df %>%
mutate(date = lubridate::date(datetime)) %>%
mutate(time_hr = lubridate::hour(datetime)) %>%
mutate(wind_thresh = ws_ms > 0.7) %>%
# filter(date >= as.Date('2018-06-01') & date <= as.Date('2018-07-01')) %>%
ggplot(aes(x = datetime, y = k_wind, group = date)) +
geom_point(aes(col = wind_thresh), size = 0.5) +
# facet_wrap(~ lubridate::month(date)) +
# facet_wrap(~ lubridate::yday(date)) +
# facet_wrap(~ lubridate::wday(date, TRUE)) +
# xlim(c(0, 24)) +
theme_bw()

Water depth
wl_df <- read_csv("data/waterlevel_qb.csv")
Parsed with column specification:
cols(
date = col_date(format = ""),
wl_m = col_double(),
datetime = col_datetime(format = "")
)
Combine data
Combine 3 data sources into one data frame (wl_df, wind_qb, temp_df)
head(wl_df) # water level is daily
[38;5;246m# A tibble: 6 x 3[39m
date wl_m datetime
[3m[38;5;246m<date>[39m[23m [3m[38;5;246m<dbl>[39m[23m [3m[38;5;246m<dttm>[39m[23m
[38;5;250m1[39m 2017-10-01 0.629 2017-10-01 [38;5;246m04:00:00[39m
[38;5;250m2[39m 2017-10-02 0.619 2017-10-02 [38;5;246m04:00:00[39m
[38;5;250m3[39m 2017-10-03 0.610 2017-10-03 [38;5;246m04:00:00[39m
[38;5;250m4[39m 2017-10-04 0.603 2017-10-04 [38;5;246m04:00:00[39m
[38;5;250m5[39m 2017-10-05 0.593 2017-10-05 [38;5;246m04:00:00[39m
[38;5;250m6[39m 2017-10-06 0.583 2017-10-06 [38;5;246m04:00:00[39m
head(wind_df) # hourly wind speed starts 6-27, includes k
[38;5;246m# A tibble: 6 x 3[39m
datetime ws_ms k_wind
[3m[38;5;246m<dttm>[39m[23m [3m[38;5;246m<dbl>[39m[23m [3m[38;5;246m<dbl>[39m[23m
[38;5;250m1[39m 2018-06-27 [38;5;246m13:55:00[39m 0.580 0.336
[38;5;250m2[39m 2018-06-27 [38;5;246m14:55:00[39m 0.616 0.379
[38;5;250m3[39m 2018-06-27 [38;5;246m15:55:00[39m 0.549 0.302
[38;5;250m4[39m 2018-06-27 [38;5;246m16:55:00[39m 0.608 0.370
[38;5;250m5[39m 2018-06-27 [38;5;246m17:55:00[39m 0.747 0.558
[38;5;250m6[39m 2018-06-27 [38;5;246m18:55:00[39m 0.685 0.469
head(temp_df) # hourly temp, starts 7-21
[38;5;246m# A tibble: 6 x 2[39m
datetime temp_C
[3m[38;5;246m<dttm>[39m[23m [3m[38;5;246m<dbl>[39m[23m
[38;5;250m1[39m 2018-07-21 [38;5;246m17:58:44[39m 26.9
[38;5;250m2[39m 2018-07-21 [38;5;246m18:58:44[39m 25.7
[38;5;250m3[39m 2018-07-21 [38;5;246m19:58:44[39m 25.2
[38;5;250m4[39m 2018-07-21 [38;5;246m20:58:44[39m 24.7
[38;5;250m5[39m 2018-07-21 [38;5;246m21:58:44[39m 24.2
[38;5;250m6[39m 2018-07-21 [38;5;246m22:58:44[39m 23.8
tail(temp_df) # ends 9-30
[38;5;246m# A tibble: 6 x 2[39m
datetime temp_C
[3m[38;5;246m<dttm>[39m[23m [3m[38;5;246m<dbl>[39m[23m
[38;5;250m1[39m 2018-09-30 [38;5;246m09:58:44[39m 18.0
[38;5;250m2[39m 2018-09-30 [38;5;246m10:58:44[39m 17.8
[38;5;250m3[39m 2018-09-30 [38;5;246m11:58:44[39m 17.7
[38;5;250m4[39m 2018-09-30 [38;5;246m12:58:44[39m 17.5
[38;5;250m5[39m 2018-09-30 [38;5;246m13:58:44[39m 17.5
[38;5;250m6[39m 2018-09-30 [38;5;246m14:49:59[39m [31mNA[39m
tail(wind_df) # ends 9-30
[38;5;246m# A tibble: 6 x 3[39m
datetime ws_ms k_wind
[3m[38;5;246m<dttm>[39m[23m [3m[38;5;246m<dbl>[39m[23m [3m[38;5;246m<dbl>[39m[23m
[38;5;250m1[39m 2018-09-30 [38;5;246m11:55:00[39m 0.234 0.054[4m6[24m
[38;5;250m2[39m 2018-09-30 [38;5;246m12:55:00[39m 0.240 0.057[4m4[24m
[38;5;250m3[39m 2018-09-30 [38;5;246m13:55:00[39m 0.25 0.062[4m5[24m
[38;5;250m4[39m 2018-09-30 [38;5;246m14:55:00[39m 0.302 0.091[4m0[24m
[38;5;250m5[39m 2018-09-30 [38;5;246m15:55:00[39m 0.273 0.074[4m7[24m
[38;5;250m6[39m 2018-09-30 [38;5;246m16:20:00[39m 0.252 0.063[4m5[24m
tail(wl_df) # ends 9-04
[38;5;246m# A tibble: 6 x 3[39m
date wl_m datetime
[3m[38;5;246m<date>[39m[23m [3m[38;5;246m<dbl>[39m[23m [3m[38;5;246m<dttm>[39m[23m
[38;5;250m1[39m 2018-08-30 0.380 2018-08-30 [38;5;246m04:00:00[39m
[38;5;250m2[39m 2018-08-31 0.369 2018-08-31 [38;5;246m04:00:00[39m
[38;5;250m3[39m 2018-09-01 0.361 2018-09-01 [38;5;246m04:00:00[39m
[38;5;250m4[39m 2018-09-02 0.350 2018-09-02 [38;5;246m04:00:00[39m
[38;5;250m5[39m 2018-09-03 0.340 2018-09-03 [38;5;246m04:00:00[39m
[38;5;250m6[39m 2018-09-04 0.328 2018-09-04 [38;5;246m04:00:00[39m
hourly time series of wind, water level, temp between 7-21 and 9-04
Rolling merge with data.table package
temp_dt <- temp_df %>%
data.table() %>%
setkey(datetime)
wind_dt <- wind_df %>%
data.table() %>%
setkey(datetime)
kdata <- temp_dt[wind_dt, roll = "nearest"]
kdata <- kdata %>%
mutate(date = lubridate::date(datetime)) %>%
left_join(dplyr::select(wl_df, -datetime))
Joining, by = "date"
write_csv(kdata, "data/kdata.csv")
Apply Calculations
Make a function that will use that as input to calculate a new column with \(k\) values.
- Calculate
dT from temperature column
- Add
temp_thresh (if temp_C < 4)
- Calculate
q (heat flux) and q_neg (if \(q < 0\))
- Calculate
Ra and Ra_thresh (if \(Ra > 8\times 10^6\))
- Determine
k_category (wind or thermal), if conditions for \(k_{thermal}\) are met: q_neg = TRUE, Ra_thresh = TRUE, or temp_thresh = TRUE.
- For rows where
k_category == "wind", calculate k_cmhr using calc_k_poindexter2a().
- For rows where
k_category == "thermal", calculate k_cmhr using calc_k_poindexter2b().
Calculate time series of \(q\) surface heat flux (\(Wm^{-2}\)) as a function of temperature time series and water column depth
- \(\frac{dT_b}{dt}\) in \(\frac{K}{sec}\) will need to convert from \(\frac{C}{hr}\)
kdf <- kdata %>%
filter(!is.na(wl_m)) %>%
# mutate(q_neg = q_wm2 <0) %>%
mutate(temp_thresh = temp_C < 4)
head(kdf)
datetime temp_C ws_ms k_wind date wl_m temp_thresh
1 2018-06-27 13:55:00 26.91349 0.5800000 0.3364000 2018-06-27 0.5550974 FALSE
2 2018-06-27 14:55:00 26.91349 0.6158333 0.3792507 2018-06-27 0.5550974 FALSE
3 2018-06-27 15:55:00 26.91349 0.5491667 0.3015840 2018-06-27 0.5550974 FALSE
4 2018-06-27 16:55:00 26.91349 0.6083333 0.3700694 2018-06-27 0.5550974 FALSE
5 2018-06-27 17:55:00 26.91349 0.7466667 0.5575111 2018-06-27 0.5550974 FALSE
6 2018-06-27 18:55:00 26.91349 0.6850000 0.4692250 2018-06-27 0.5550974 FALSE
Crop to just July 24 - August 24
kdf <- kdf %>%
dplyr::filter(date >= as.Date('2018-07-23') & date <= as.Date('2018-08-24'))
kdf %>%
dplyr::select(-date, -temp_thresh, -k_wind) %>%
tidyr::gather(variable, value, temp_C:wl_m) %>%
ggplot(aes(x = datetime, y = value)) +
geom_line() +
facet_wrap(vars(variable), scales = "free_y", ncol = 1) +
theme_bw()

Heat flux
kdf$dtemp <- c(NA, diff(kdf$temp_C)) # revisit for smoothing
kdf %>%
# slice(-1) %>%
mutate(dt_pos = dtemp>0) %>%
ggplot(aes(x = datetime, y = temp_C)) +
geom_line(col = "gray") +
geom_point(aes(col = dt_pos)) + theme_bw()

kdf$q_wm2 <- pmap_dbl(list(temp_C = kdf$temp_C,
waterdepth_m = kdf$wl_m,
dT = kdf$dtemp),
calc_q_heatflux)
kdf %>%
mutate(dt_pos = dtemp>0) %>%
ggplot(aes(x = datetime, y = q_wm2)) +
geom_line(col = "gray") +
geom_point(aes(col = dt_pos)) + theme_bw()

# kdf$Ra <- kdf %>% pmap_dbl(calc_rayleigh())
kdf$Ra <- pmap_dbl(list(q = kdf$q_wm2,
temp_C = kdf$temp_C,
lscale = kdf$wl_m),
calc_rayleigh)
kdf$Ra_thresh <- kdf$Ra > 8e6
kdf %>%
ggplot(aes(x = datetime, y = Ra)) +
geom_line(col = "gray") +
geom_point(aes(col = Ra_thresh)) + theme_bw()

# kdf <-
kdf %>%
mutate(q_pos = q >=0) %>% View()
Error in mutate_impl(.data, dots) :
Evaluation error: comparison (5) is possible only for atomic and list types.
purrr::pmap_dbl(list(q = kdf_thermal$q_wm2, temp_C = kdf_thermal$temp_C),
calc_k_poindexter2b) %>% head()
[1] 0.2875823 0.3616141 0.3703332 0.3968111 0.3660502 0.3744688
kdf_join %>%
mutate(k_mix = dplyr::case_when(
k_category == "wind" ~ k_wind,
k_category == "thermal" ~ k_thermal
)) %>% head(10)
datetime temp_C ws_ms k_wind date wl_m temp_thresh dtemp q_wm2 Ra
1 2018-07-23 00:55:00 22.55509 0.3558333 0.1266174 2018-07-23 0.4849155 FALSE NA NA NA
2 2018-07-23 01:55:00 22.55139 0.3812500 0.1453516 2018-07-23 0.4849155 FALSE -0.003703704 -2.083821 NaN
3 2018-07-23 02:55:00 22.54213 0.4425000 0.1958063 2018-07-23 0.4849155 FALSE -0.009259259 -5.209564 NaN
4 2018-07-23 03:55:00 22.54815 0.4829167 0.2332085 2018-07-23 0.4849155 FALSE 0.006018519 3.386212 5449991329
5 2018-07-23 04:55:00 22.53796 0.6050000 0.3660250 2018-07-23 0.4849155 FALSE -0.010185185 -5.730526 NaN
6 2018-07-23 05:55:00 22.52454 0.5762500 0.3320641 2018-07-23 0.4849155 FALSE -0.013425926 -7.553898 NaN
7 2018-07-23 06:55:00 22.53472 0.5154167 0.2656543 2018-07-23 0.4849155 FALSE 0.010185185 5.730530 8081523609
8 2018-07-23 07:55:00 22.54167 0.5283333 0.2791361 2018-07-23 0.4849155 FALSE 0.006944444 3.907173 6065690561
9 2018-07-23 08:55:00 22.53194 0.5337500 0.2848891 2018-07-23 0.4849155 FALSE -0.009722222 -5.470055 NaN
10 2018-07-23 09:55:00 22.52130 0.5654167 0.3196960 2018-07-23 0.4849155 FALSE -0.010648148 -5.991027 NaN
Ra_thresh k_category q_pos k_thermal k_mix
1 NA <NA> NA NA NA
2 NA thermal FALSE 0.2875823 0.2875823
3 NA thermal FALSE 0.3616141 0.3616141
4 TRUE wind TRUE NA 0.2332085
5 NA thermal FALSE 0.3703332 0.3703332
6 NA thermal FALSE 0.3968111 0.3968111
7 TRUE wind TRUE NA 0.2656543
8 TRUE wind TRUE NA 0.2791361
9 NA thermal FALSE 0.3660502 0.3660502
10 NA thermal FALSE 0.3744688 0.3744688

Notes
Ideas
Compare methane flux and k measurements with and without changing water levels - what is the effect of including changing water level? what is the relative importance of a) changing areal extent of water surface to scale flux by? b) change in k value and k category on the magnitude of the flux? c) dilution effect of the methane concentration in the water?
Surface heat flux approach in Read et al. 2012 assumes that sediment heating, advected components, and changes in water levels are negligible. These assumptions do not hold in delmarva bay wetland systems!
Delmarva bay wetland sites are sheltered by tree canopy which affects the wind shear driven gas exchange. Read et al. method using approach of scaling the effect of wind sheltering where the size of the lake is small enough, so k is reduced for area affected by sheltering as a function of distance from tree canopy. Unlike that method, there is no water surface area that is unaffected by effects of canopy sheltering. Canopy height measurements from Dubayah et al. CMS product.
In-canopy wind speed is calculated in Poindexter et al. method, as a function of wind speed measured at 10m.
Our measurements of wind speed can be used to evaluate the other methods, by comparing measured in-canopy wind speed to wind speed from a nearby weather station (measured above the canopy). Need to find a local weather station to do that?
Need to understand what the enhancement factor is all about - can I just use \(k = \langle U_{canopy}\rangle^2(\frac{Sc}{600})^{-n}\) - additional factor beyond mean wind speed to characterize effect of wind on \(k\) because the largest scale eddies in the canopy wind field are highly intermittent. Poindexter and Variano 2013 give a relationship for the \(k_{600}\) enhancement factor as a fucntion of \(\frac{\langle(U_{canopy}-\langle U_{canopy}\rangle)^2\rangle^{\frac{1}{2}}}{\langle U_{canopy}\rangle}\). The effect of the gusts is interactions between the wind and plant canopy that generates intermittent, large-scale eddies, which presumably are the gusts that enhance gas exchange in natural wetlands.
Compare wind gust speeeds and wind speeds from sonic anemometer measurements to help think about this.
gusts <- read_csv("data/windgusts_qb.csv")
gusts %>%
mutate(date = lubridate::date(datetime)) %>%
mutate(time_hr = lubridate::hour(datetime)) %>%
# filter(date >= as.Date('2018-06-01') & date <= as.Date('2018-07-01')) %>%
ggplot(aes(x = time_hr, y = gusts_ms, group = date)) +
geom_line(aes(col = date)) +
# facet_wrap(~ lubridate::month(date)) +
# facet_wrap(~ lubridate::yday(date)) +
# facet_wrap(~ lubridate::wday(date, TRUE)) +
xlim(c(0, 24)) +
theme_bw()

Other relevant studies
- Godwin et al. 2013 JGR Evening methane emission events - found that timing of nighttime emission events (as measured by flux towers) coincided with cooling and convective mixing within hollows, which occurred regularly during the growing season. They propose that diurnal thermal stratification in shallow pools traps methane by limiting turbulent transport, and this methane stored during daytime heating is later released during evening cooling due to convective turbulent mixing.
- Happell et al. 1995 used floating chamber measurements in a Florida hardwood swamp and found \(k_{600}\) values averaged \(0.78\pm 0.54 cm h^{-1}\)
- Variano et al. 2009 - \(SF_6\) tracer released in the patterned marshes of the Florida Everglades indicated \(k_{600}\) there ranged from 0.3 to 1.8 cm h^-1
- Sebacher et al. 1983 measured gas exchange in a wetland pond free of emergent vegetation and wind speed 2 cm above the water surface, wind speed around 0.8 m s^-1.
LS0tCnRpdGxlOiAiR2FzIGV4Y2hhbmdlIGluIERlbG1hcnZhIGJheXMiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDIKICAgIHRvY19mbG9hdDogdHJ1ZQplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KYGBge3Igc2V0dXAsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoQ0hOT1NaKQpkYXRhKHRoZXJtbykKbGlicmFyeSh4dHMpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZHlncmFwaHMpCmxpYnJhcnkocHVycnIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShmb3JjYXRzKQpgYGAKCkNhbGN1bGF0ZSBhIHRpbWUgc2VyaWVzIG9mICRrJCBpbiAkXGZyYWN7Y219e2hyfSQgdXNpbmcgaW5wdXRzOiB3YXRlciB0ZW1wZXJhdHVyZSwgd2F0ZXIgZGVwdGgsIHdpbmQgc3BlZWQuICRrJCBpcyBjYWxjdWxhdGVkIHVzaW5nIGVxdWF0aW9uIDIgaW4gUG9pbmRleHRlciBldCBhbC4gMjAxNiwgd2hpY2ggdXNlcyBhIGRpZmZlcmVudCBmb3JtdWxhdGlvbiBmb3Igd2luZC1kcml2ZW4gdnMuIHRoZXJtYWwgY29udmVjdGlvbiBkcml2ZW4gZ2FzIGV4Y2hhbmdlIGJhc2VkIG9uIHRocmVzaG9sZHMgZm9yIGhlYXQgZmx1eC4gCgojIEJhY2tncm91bmQKCiMjIEdhcyBmbHV4IGVxdWF0aW9uCgokRmx1eCA9IGsoQ197ZXF9IC0gQ193KSQKCiRrJCBpcyB0eXBpY2FsbHkgcmVwb3J0ZWQgYXMgJGtfezYwMH0kIHRvIGZhY2lsaXRhdGUgY29tcGFyaXNvbi4gCgoka197NjAwfSA9IGsoXGZyYWN7NjAwfXtTY30pXnstbn0kCgokbiQgaXMgYSBmYWN0b3IgY2hhcmFjdGVyaXppbmcgdGhlIGtpbmVtYXRpYyBiZWhhdmlvciBvZiB0aGUgd2F0ZXIgc3VyZmFjZS4gCgojIyBQcmV2aW91cyBzdHVkaWVzIAoKVGhlIG1vc3QgcmVsZXZhbnQgc3R1ZGllcyBvbiBjYWxjdWxhdGluZyBnYXMgZXhjaGFuZ2UgYXJlOgoKKiBSZWFkIGV0IGFsLiAyMDEyCiogSG9sZ2Vyc29uIGV0IGFsIDIwMTcKKiBNYWNJbnR5cmUgZXQgYWwuIDIwMTAgLSBtb2RlbCAkayQgd2l0aCB0d28gZnVuY3Rpb25zIG9mICRVX3sxMH0kLCBvbmUgZm9yIHBlcmlvZHMgb2Ygc3VyZmFjZSBoZWF0IGxvc3MgYW5kIG9uZSBmb3IgcGVyaW9kcyBvZiBoZWF0IGdhaW4KKiBTb2xvdmlldiBldCBhbC4gMjAwNyAtIGNvbWJpbmVkIGVmZmVjdHMgb2Ygc3VyZmFjZSBoZWF0IGxvc3MgYW5kIHdpbmQgdmlhIHN1cmZhY2UgZGlzc2lwYXRpb24gb2YgdHVyYnVsZW50IGtpbmV0aWMgZW5lcmd5IChmcm9tIGNvbWJpbmVkIGVmZmVjdHMgb2YgYnVveWFuY3ksIHdpbmQgc2hlYXIsIHdhdmUgYnJlYWtpbmcpCiogUG9pbmRleHRlciBhbmQgVmFyaWFubyAyMDEzIC0gZGV2ZWxvcCBhbiBhbmFseXRpY2FsIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHN1cmZhY2UgaGVhdCBmbHV4ICRxJCBhbmQgJGskIChiYXNlZCBvbiBsYWJvcmF0b3J5IG1lYXN1cmVtZW50cykKKiBQb2luZGV4dGVyIGV0IGFsLiAyMDE2CgpQb2luZGV4dGVyIGFuZCBWYXJpYW5vICgyMDEzKSBkZXZlbG9wZWQgbmV3IG1vZGVscyBmb3Igd2V0bGFuZHMgd2l0aCBlbWVyZ2VudCB2ZWdldGF0aW9uLCBiYXNlZCBvbiB0aGUgaWRlYSB0aGF0IGVtZXJnZW50IHZlZ2V0YXRpb24gd291bGQgYXR0ZW51YXRlIHdpbmQgc3BlZWQgYWJvdmUgdGhlIHdhdGVyIHN1cmZhY2UsIG1vZGlmeSBmbHVpZCBzaGVhciBhdCB0aGUgd2F0ZXIgc3VyZmFjZSwgYW5kIGluZmx1ZW5jZSBzdGlycmluZyBiZW5lYXRoIHRoZSB3YXRlciBzdXJmYWNlLiBUaGV5IGZvY3VzIG9uIHRoZXJtYWwgY29udmVjdGlvbiwgcGFyYW1ldGVyaXplZCBmcm9tIHN1cmZhY2UgaGVhdCBsb3NzLCBhbmQgd2luZCBzaGVhciwgcGFyYW1ldGVyaXplZCB1c2luZyB0aGUgbWVhbiB3aW5kIHNwZWVkIGluIHRoZSBjb25zdGFudC12ZWxvY2l0eSBvciBzaGVhci1mcmVlIHJlZ2lvbiBvZiB0aGUgdmVnZXRhdGlvbiBjYW5vcHkuICAKCkZvcmVzdGVkIHdldGxhbmRzIGxpa2UgRGVsbWFydmEgYmF5cyBjYW4gYmUgaW51bmRhdGVkIGFyZWFzIHdpdGhvdXQgZW1lcmdlbnQgdmVnZXRhdGlvbiAoZS5nLiBmb3Jlc3RlZCBwb25kcyksIHdoZXJlIHRyZWUgY2Fub3B5IGF0dGVudWF0ZXMgd2luZCBzcGVlZCBidXQgZWZmZWN0cyBvZiBwbGFudCBzdGVtcyBhcmUgbm90IGFzIHJlbGV2YW50LiAKClVzaW5nIFBvaW5kZXh0ZXIgZXQgYWwgMjAxNiBtZXRob2QgZm9yIHdldGxhbmQgcGVyc3BlY3RpdmUsIHdoZXJlIGVtZXJnZW50IHZlZ2V0YXRpb24gYW5kIHN1cmZhY3RhbnRzIGFyZSBpbXBvcnRhbnQuIE5ldyByZWxhdGlvbnNoaXBzIGZvciAkayQgZGVzaWduZWQgc3BlY2lmaWNhbGx5IGZvciB1c2UgaW4gdGhlIHByZXNlbmNlIG9mIGFuIGVtZXJnZW50IHZlZ2V0YXRpb24gY2Fub3B5LiBCYXNlZCBvbiBsYWIgbWVhc3VyZW1lbnRzIHdpdGggYSBtb2RlbCB3ZXRsYW5kLCB3aGljaCBzdWdnZXN0ZWQgYSBxdWFkcmF0aWMgcmVsYXRpb25zaGlwIGJldHdlZW4gJGskIGFuZCB0aGUgbWVhbiBpbi1jYW5vcHkgd2luZCBzcGVlZCAoUG9pbmRleHRlciBhbmQgVmFyaWFubywgMjAxMykuIAoKJGskIGlzIHdpbmQtZHJpdmVuIHdoZW4gJHEgXGdlcSAwJCBvciAkUmEgPCA4IFx0aW1lcyAxMF42JCwgYW5kIHRoZXJtYWwgY29udmVjdGlvbiBkcml2ZW4gd2hlbiAkcSA8IDAkIGFuZCAkUmEgPiA4IFx0aW1lcyAxMF42JC4gJFJhJCBpcyB0aGUgUmF5bGVpZ2ggbnVtYmVyLCBhIGZ1bmN0aW9uIG9mIGhlYXQgZmx1eC4gV2hlbiAkUmEkIGlzIGJlbG93IGEgY3JpdGljYWwgdmFsdWUgZm9yIGEgZmx1aWQsIHRoZW4gaGVhdCB0cmFuc2ZlciBpcyBwcmltYXJpbHkgaW4gdGhlIGZvcm0gb2YgY29uZHVjdGlvbjsgd2hlbiBpdCBleGNlZWRzIHRoYXQgdmFsdWUgdGhlbiBoZWF0IHRyYW5zZmVyIGlzIHByaW1hcmlseSBpbiB0aGUgZm9ybSBvZiBjb252ZWN0aW9uLiAqRXhjZXB0IGlmIHdhdGVyIHRlbXBlcmF0dXJlIGlzIGJlbG93IDQgZGVnIEMsIHRoZW4gJFxiZXRhJCBjaGFuZ2VzIHNpZ24gYW5kICRrJCBpcyB0aGVybWFsbHkgZHJpdmVuIGJ5ICRxID4gMCQuIAoKKiBGaXJzdCBjaGVjayBpZiAkcVxnZXEgMCQsIGlmIHllcywgdXNlICRrX3t3aW5kfSQgdW5sZXNzIHdhdGVyIHRlbXAgPCA0LgoqIElmICRxIDwgMCQsIHVzZSAka197dGhlcm1hbH0kIHVubGVzcyAkUmEgPCA4XHRpbWVzIDEwXjYkLgoKIyBTdXJmYWNlIEhlYXQgRmx1eAoKU3VyZmFjZSBoZWF0IGZsdXggJChxKSQgY2FuIGJlIHVzZWQgdG8gZXN0aW1hdGUgdGhlcm1hbCBjb252ZWN0aW9uLiBOZWdhdGl2ZSBoZWF0IGZsdXhlcyBpbmRpY2F0ZSBhIGNvb2xpbmcgd2F0ZXIgY29sdW1uICh3YXRlciBsb3NpbmcgaGVhdCB0byB0aGUgYWlyKSBhbmQgcG9zaXRpdmUgaGVhdCBmbHV4IG1lYW5zIHRoZSB3YXRlciBjb2x1bW4gaXMgd2FybWluZy4gVHlwaWNhbCB2YWx1ZXMgb2YgJHEkIGluIHRlbXBlcmF0ZSB3ZXRsYW5kcyBhcmUgLTIwMCB0byAzMDAgVyBtXi0yLiBDb252ZWN0aXZlIG1peGluZyBvY2N1cnMgd2hlbiB0aGUgd2F0ZXIgaXMgbG9zaW5nIGhlYXQgdG8gdGhlIGFpciAkKHEgPCAwKSQuCgokcSA9IFxmcmFje2RUX2J9e2R0fVxyaG8gY19wSCQKCiogJGNfcCQgaXMgdGhlIGlzb2JhcmljIGhlYXQgY2FwYWNpdHkgKGlzb2JhcmljID0gY29uc3RhbnQgcHJlc3N1cmUpLCBpbiAkXGZyYWN7Sn17a2dLfSQKKiAkXHJobyQgaXMgd2F0ZXIgZGVuc2l0eSwgaW4gJFxmcmFje2tnfXttXjN9JAoqICRIJCBpcyB0aGUgZGVwdGggb2YgdGhlIHdhdGVyIGNvbHVtbiwgaW4gbWV0ZXJzCiogJFRfYiQgaXMgdGhlIGJ1bGsgd2F0ZXIgdGVtcGVyYXR1cmUKCgpDYWxjdWxhdGUgJHEkLCB1c2luZyBmdW5jdGlvbnMgZnJvbSB0aGUgYENITk9TWmAgcGFja2FnZSB0byBjYWxjdWxhdGUgd2F0ZXIgZGVuc2l0eSBhbmQgaXNvYmFyaWMgaGVhdCBjYXBhY2l0eQoKYGBge3J9CmNhbGNfcV9oZWF0Zmx1eCA8LSBmdW5jdGlvbih0ZW1wX0MsIHdhdGVyZGVwdGhfbSwgZFQsIGR0X3NlYyA9IDM2MDApewogICMgaXNvYmFyaWMgaGVhdCBjYXBhY2l0eSBjYWwgS14tMSBtb2xeLTEKICBjcCA9IGFzLm51bWVyaWMoCiAgICBDSE5PU1o6OndhdGVyKCJDcCIsIFQgPSAyNzMuMTUgKyB0ZW1wX0MpKQogICMgd2F0ZXIgZGVuc2l0eSBrZyBtXi0zCiAgcmhvID0gYXMubnVtZXJpYygKICAgIENITk9TWjo6d2F0ZXIoInJobyIsIFQgPSAyNzMuMTUgKyB0ZW1wX0MpKQogICMgY29udmVydCBjcCB0byBKIGtnXi0xIEteLTEKICBjcCA9IGNwKig0LjE4NC8wLjAxOCkKICAKICBxX3dtMiA8LSAoZFQvZHRfc2VjKSAqIHJobyAqIGNwICogd2F0ZXJkZXB0aF9tCiAgcmV0dXJuKHFfd20yKQp9CmBgYAoKIyBSYXlsZWlnaCBOdW1iZXIgY2FsY3VsYXRpb24KClVzZWQgaW4gY29tYmluYXRpb24gd2l0aCAkcSQgdG8gZGV0ZXJtaW5lIHdoaWNoIGZvcm11bGEgdG8gdXNlIGZvciBjYWxjdWxhdGlvbiBvZiAkayQuIAoKJFJhID0gNC43KFxmcmFjey1xZ1xiZXRhIExeNH17XGFscGhhXjJ2Y19wXHJob30pXntcZnJhY3szfXs0fX0kCgoqICRnJCAtIGFjY2VsZXJhdGlvbiBkdWUgdG8gZ3Jhdml0eQoqICRxJCAtIHdhdGVyIGNvbHVtbiBoZWF0IGZsdXgKKiAkTCQgLSBjaGFyYWN0ZXJpc3RpYyBsZW5ndGggc2NhbGUsIHdldGxhbmQgZGVwdGgKClBvaW5kZXh0ZXIgYW5kIFZhcmlhbm8gKDIwMTMpIGZpbmQgdGhhdCB1c2luZyB0aGUgd2V0bGFuZCBkZXB0aCBhcyB0aGUgbGVuZ3RoIHNjYWxlICRMJCwgdGhlIFJheWxlaWdoIG51bWJlciB0aHJlc2hvbGQgaXMgbWV0IGZvciB3ZXRsYW5kIHdhdGVyIGNvbHVtbnMgZGVlcGVyIHRoYW4gMTBjbSBmb3IgdHlwaWNhbCBoZWF0IGxvc3MgcmF0ZXMuIAoKKiAkXGJldGEkIC0gdGhlcm1hbCBleHBhbnNpb24gY29lZmZpY2llbnQKKiAkXGFscGhhJCAtIHRoZXJtYWwgZGlmZnVzaXZpdHkKKiAkdiQgLSBraW5lbWF0aWMgdmlzY29zaXR5CiogJGNfcCQgLSBoZWF0IGNhcGFjaXR5IGF0IGNvbnN0YW50IHByZXNzdXJlCiogJFxyaG8kIC0gZGVuc2l0eQoKYGBge3J9CmNhbGNfcmF5bGVpZ2ggPC0gZnVuY3Rpb24ocSwgdGVtcF9DID0gMjUsIGxzY2FsZSA9IDEpewogIGcgPSAtOS44ICMgbSBzXi0yCiAgYmV0YSA9IGFzLm51bWVyaWMoCiAgICBDSE5PU1o6OndhdGVyKCJhbHBoYSIsIFQgPSAyNzMuMTUgKyB0ZW1wX0MpKSAjIEteLTEKICBhbHBoYSA9IGFzLm51bWVyaWMoCiAgICBDSE5PU1o6OndhdGVyKCJ0ZGlmZiIsIFQgPSAyNzMuMTUgKyB0ZW1wX0MpKSAjY21eMiBzXi0xCiAga3YgPSBhcy5udW1lcmljKAogICAgQ0hOT1NaOjp3YXRlcigidmlzY2siLCBUID0gMjczLjE1ICsgdGVtcF9DKSkgI2NtXjIgc14tMQogIGNwID0gYXMubnVtZXJpYygKICAgIENITk9TWjo6d2F0ZXIoIkNwIiwgVCA9IDI3My4xNSArIHRlbXBfQykpCiAgcmhvID0gYXMubnVtZXJpYygKICAgIENITk9TWjo6d2F0ZXIoInJobyIsIFQgPSAyNzMuMTUgKyB0ZW1wX0MpKSAjIGtnIG1eLTMKCiAgIyBjb252ZXJ0IGNtIHRvIG0KICBhbHBoYSA9IGFscGhhLzEwMDAwCiAga3YgPSBrdi8xMDAwMAogIAogIHJhIDwtIDQuNyooKC1xKmcqYmV0YSpsc2NhbGVeNCkvCiAgICAgICAoYWxwaGFeMiprdipjcCpyaG8pKV4oMy80KQogIHJldHVybihyYSkKfQpgYGAKCmBgYHtyfQpjYWxjX3JheWxlaWdoKHEgPSAuMSwgdGVtcF9DID0gMzAsIGxzY2FsZSA9IC4xMCkKY2FsY19yYXlsZWlnaChxID0gLjEwLCB0ZW1wX0MgPSAzMCwgbHNjYWxlID0gLjEwKSA+IDhlNgpgYGAKCgojIFRoZXJtYWwgY29udmVjdGlvbiBLCgpGcm9tIFBvaW5kZXh0ZXIgZXQgYWwuIDIwMTYgKEdSTCksIGEgc2VtaS1lbXByaWNhbCBmdW5jdGlvbiBkZXJpdmVkIGZyb20gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGhlYXQgZmx1eCBhbmQgdGhlcm1hbCBjb252ZWN0aW9uLCB3aGljaCBpcyBzaW1pbGFyIHRvIHRoZSBzdXJmYWNlIHJlbmV3YWwgbW9kZWxzIHVzZWQgZm9yIHBlcmlvZHMgb2YgcmVsYXRpdmUgY2FsbSBpbiBsYWtlcyBhbmQgb2NlYW5zIGJ5IFJlYWQgZXQgYWwuIDIwMTIgYW5kIFNvbG92aWV2IGV0IGFsLiAyMDA3LiAKCiRrID0gMC4xNF57XGZyYWN7M317NH19KFxmcmFjey1xZ1xiZXRhXGFscGhhXjJ9e3ZjX3BccmhvfSlee1xmcmFjezF9ezR9fShcZnJhY3tTY317UHJ9KV57LW59JAoKKiAkcSQgLSB3YXRlciBjb2x1bW4gaGVhdCBmbHV4LCBjYWxjdWxhdGVkIGZyb20gcmF0ZSBvZiBjaGFuZ2UgaW4gd2V0bGFuZCB3YXRlciBjb2x1bW4gdGVtcGVyYXR1cmUgd2l0aCB0aW1lIChkZXNjcmliZWQgaW4gc3VwcG9ydGluZyBpbmZvKSAKKiAkZyQgLSBhY2NlbGVyYXRpb24gZHVlIHRvIGdyYXZpdHkKKiAkU2MkIC0gU2NobWlkdCBudW1iZXIKCkZ1bmN0aW9ucyBvZiB3YXRlciB0ZW1wZXJhdHVyZSBhbmQgYXRtb3NwaGVyaWMgcHJlc3N1cmU6CgoqICRcYmV0YSQgLSB0aGVybWFsIGV4cGFuc2lvbiBjb2VmZmljaWVudAoqICRcYWxwaGEkIC0gdGhlcm1hbCBkaWZmdXNpdml0eQoqICR2JCAtIGtpbmVtYXRpYyB2aXNjb3NpdHkKKiAkY19wJCAtIGhlYXQgY2FwYWNpdHkgYXQgY29uc3RhbnQgcHJlc3N1cmUKKiAkXHJobyQgLSBkZW5zaXR5CiogJFByJCAtIFByYW5kdGwgbnVtYmVyCgpDYWxjdWxhdGUgayBmb3IgdGhlcm1hbCBjb252ZWN0aW9uCgpgYGB7cn0KY2FsY19rX3BvaW5kZXh0ZXIyYiA8LSBmdW5jdGlvbihxLCB0ZW1wX0MsIG5fc3VyZmFjZSA9ICgyLzMpKXsKICAjIGlmKHEgPCAwKXtzdG9wKCJOZWdhdGl2ZSBoZWF0IGZsdXguIAogICMgICAgICAgICAgICAgICAgUGxlYXNlIHVzZSB3aW5kIG1vZGVsIHRvIGNhbGN1bGF0ZSBLLiIpfQogIGcgPSA5LjggIyBtIHNeLTIKICBiZXRhID0gYXMubnVtZXJpYygKICAgIENITk9TWjo6d2F0ZXIoImFscGhhIiwgVCA9IDI3My4xNSArIHRlbXBfQykpICMgS14tMQogIGFscGhhID0gYXMubnVtZXJpYygKICAgIENITk9TWjo6d2F0ZXIoInRkaWZmIiwgVCA9IDI3My4xNSArIHRlbXBfQykpICNjbV4yIHNeLTEKICBrdiA9IGFzLm51bWVyaWMoCiAgICBDSE5PU1o6OndhdGVyKCJ2aXNjayIsIFQgPSAyNzMuMTUgKyB0ZW1wX0MpKSAjY21eMiBzXi0xCiAgY3AgPSBhcy5udW1lcmljKAogICAgQ0hOT1NaOjp3YXRlcigiQ3AiLCBUID0gMjczLjE1ICsgdGVtcF9DKSkKICByaG8gPSBhcy5udW1lcmljKAogICAgQ0hOT1NaOjp3YXRlcigicmhvIiwgVCA9IDI3My4xNSArIHRlbXBfQykpICMga2cgbV4tMwogIFByID0gYXMubnVtZXJpYygKICAgIENITk9TWjo6d2F0ZXIoIlBybmR0bCIsIFQgPSAyNzMuMTUgKyB0ZW1wX0MpKQogIFNjID0gNjAwCiAgCiAgIyBjb252ZXJ0IGNwIHRvIEoga2deLTEgS14tMQogIGNwID0gY3AqKDQuMTg0LzAuMDE4KQogICMgY29udmVydCBjbSB0byBtCiAgYWxwaGEgPSBhbHBoYS8xMDAwMAogIGt2ID0ga3YvMTAwMDAKICAKICBrID0gKDAuMTReKDMvNCkpICoKICAgICgoLXEgKiBnICogYmV0YSAqIGFscGhhXjIpLyhrdiAqIGNwICogcmhvKSleKDEvNCkgKiAKICAgIChTYy9QcileKC1uX3N1cmZhY2UpCiAgCiAga19jbWhyID0gayoxMDAqMzYwMAogIHJldHVybihrX2NtaHIpCn0KYGBgCgpgYGB7cn0KY2FsY19rX3BvaW5kZXh0ZXIyYihxID0gNTAsIHRlbXBfQyA9IDI1KSAjIGNtL2hyCmNhbGNfa19wb2luZGV4dGVyMmIocSA9IC01MCwgdGVtcF9DID0gMjUpICMgY20vaHIKYGBgCgoKIyBXaW5kLWRyaXZlbiBrCgokayA9IDNcR2FtbWF7XGxhbmdsZSBVX3tjYW5vcHl9fVxyYW5nbGVeMiAoXGZyYWN7U2N9ezYwMH0pXnstbn0kCgoqICRcR2FtbWEkIGVuaGFuY2VtZW50IGZhY3RvciB0byBhY2NvdW50IGZvciBmbHVjdHVhdGlvbnMgdGhhdCBpbmNyZWFzZSB0aGUgZ2FzIHRyYW5zZmVyIHZlbG9jaXR5IHJlbGF0aXZlIHRvIHZhbHVlIHByZWRpY3RlZCBmcm9tIG1lYW4gd2luZCBzcGVlZCBhbG9uZS4gUG9pbmRleHRlciBldCBhbC4gdXNlICRcR2FtbWEgPSAwLjMyJCBiYXNlZCBvbiBpbi1jYW5vcHkgd2luZCBzcGVlZCBtZWFzdXJlbWVudHMgYXQgdGhlaXIgbWFyc2ggc3R1ZHkgc2l0ZS4gKFBvaW5kZXh0ZXIgYW5kIFZhcmlhbm8gdXNlIDEuMyB0aG91Z2g/KQoqICRVX3tjYW5vcHl9JCBpcyBtZWFuIGluLWNhbm9weSB3aW5kIHNwZWVkLCB3aGljaCBjYW4gYmUgY29tcHV0ZWQgZnJvbSB3aW5kIHNoZWFyIHN0cmVzcyBhbmQgd2luZCBzcGVlZCBtZWFzdXJlZCBhYm92ZSB0aGUgY2Fub3B5IChidXQgaXMgYmVpbmcgbW9uaXRvcmVkIGF0IHNpdGVzIFFCIGFuZCBORCkKCkNhbGN1bGF0ZSBrIGZvciB3aW5kIGRyaXZlbiB0dXJidWxlbmNlLgoKYGBge3J9CmNhbGNfa19wb2luZGV4dGVyMmEgPC0gZnVuY3Rpb24od3MsIGdhbW1hID0gKDEvMyksIFNjID0gNjAwLCBuX3N1cmZhY2UgPSAoMi8zKSl7CiAgayA9IDMqZ2FtbWEqKHdzKV4yICogKFNjLzYwMCleKC1uX3N1cmZhY2UpCiAgcmV0dXJuKGspCn0KYGBgCgpJbi1jYW5vcHkgd2luZCBzcGVlZCBpcyBhc3N1bWVkIHRvIGJlIGluIHRoZSB6b25lIHdoZXJlIHdpbmQgc3BlZWQgcHJvZmlsZSBpcyB2ZXJ0aWNhbD8gCgojIERhdGEKCkxvYWQgZGF0YSB0byB1c2UgdGhlIGVxdWF0aW9ucyBhYm92ZSBmb3IgY2FsY3VsYXRpbmcgJGskLiBBZ2dyZWdhdGUgaGlnaCByZXNvbHV0aW9uIGRhdGEgdG8gaG91cmx5IG1lYW5zLiAKCiMjIyBUZW1wZXJhdHVyZQoKV2F0ZXIgdGVtcGVyYXR1cmUgbWVhc3VyZWQgYXQgMyBsb2NhdGlvbnMgaW4gYSB2ZXJ0aWNhbCBwcm9maWxlLCBpbiAyIHdldGxhbmRzLiBOZWVkIHRvIGNvbXBhcmUgd2l0aCB3YXRlciBsZXZlbCB0byBkZXRlcm1pbmUgd2hlbiBzZW5zb3JzIHdlcmUgaW4gdGhlIHdhdGVyIGFuZCB3aGVuIHRoZXkgd2VyZSBleHBvc2VkIChhbHNvIGV2aWRlbnQgYnkgbG9va2luZyBhdCBkYWlseSBmbHVjdHVhdGlvbnMpLgoKTG9vayBhdCB0eXBpY2FsIGRhaWx5IHRpbWUgc2VyaWVzIHBhdHRlcm4gb2YgdGVtcGVyYXR1cmUgaW4gdGhlIHdhdGVyIGNvbHVtbiwgdG8gZGV0ZXJtaW5lIGhvdyB0byBjYWxjdWxhdGUgJFxmcmFje2RUfXtkdH0kLiBQb2luZGV4dGVyIGFuZCBWYXJpYW5vIHVzZSBsaW5lYXIgcmVncmVzc2lvbiBvZiB0ZW1wZXJhdHVyZSByZWFkaW5ncyBkdXJpbmcgdGhlaXIgZXhwZXJpbWVudHMuIAoKYGBge3J9CnRlbXBfZGYgPC0gcmVhZF9jc3YoImRhdGEvd2F0ZXJ0ZW1wX3FiTUlELmNzdiIpCmBgYAoKIyMjIFdpbmQKCkluLWNhbm9weSB3aW5kIHNwZWVkIG1lYXN1cmVkIHdpdGggc29uaWMgYW5lbW9tZXRlcnMgYXBwcm94aW1hdGVseSAxbSBvdmVyIHRoZSB3YXRlciBzdXJmYWNlICh2YXJpZXMgYmV0d2VlbiB4eCBhbmQgeHggZHVlIHRvIGNoYW5nZXMgaW4gd2F0ZXIgbGV2ZWwpLiAKCmBgYHtyfQp3aW5kX2RmIDwtIHJlYWRfY3N2KCJkYXRhL3dpbmRzcGVlZF9xYi5jc3YiKQpgYGAKCgpgYGB7cn0Kd2luZF9kZiAlPiUgCiAgbXV0YXRlKGRhdGUgPSBsdWJyaWRhdGU6OmRhdGUoZGF0ZXRpbWUpKSAlPiUKICBtdXRhdGUodGltZV9ociA9IGx1YnJpZGF0ZTo6aG91cihkYXRldGltZSkpICU+JSAKICAjIGZpbHRlcihkYXRlID49IGFzLkRhdGUoJzIwMTgtMDYtMDEnKSAmIGRhdGUgPD0gYXMuRGF0ZSgnMjAxOC0wNy0wMScpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB0aW1lX2hyLCB5ID0gd3NfbXMsIGdyb3VwID0gZGF0ZSkpICsKICBnZW9tX2xpbmUoYWVzKGNvbCA9IGRhdGUpKSArCiAgIyBmYWNldF93cmFwKH4gbHVicmlkYXRlOjptb250aChkYXRlKSkgKwogICMgZmFjZXRfd3JhcCh+IGx1YnJpZGF0ZTo6eWRheShkYXRlKSkgKwogICMgZmFjZXRfd3JhcCh+IGx1YnJpZGF0ZTo6d2RheShkYXRlLCBUUlVFKSkgKwogIHhsaW0oYygwLCAyNCkpICsKICB0aGVtZV9idygpCmBgYAoKd2luZC1kcml2ZW4gayBpcyBqdXN0IGEgZnVuY3Rpb24gb2Ygd2luZCBzcGVlZAoKYGBge3J9CndpbmRfZGYgPC0gd2luZF9kZiAlPiUKICBtdXRhdGUoa193aW5kID0gbWFwX2RibCh3c19tcywgfmNhbGNfa19wb2luZGV4dGVyMmEod3MgPSAueCkpKQpgYGAKCmBgYHtyfQp3aW5kX2RmICU+JQogIG11dGF0ZShkYXRlID0gbHVicmlkYXRlOjpkYXRlKGRhdGV0aW1lKSkgJT4lCiAgbXV0YXRlKHRpbWVfaHIgPSBsdWJyaWRhdGU6OmhvdXIoZGF0ZXRpbWUpKSAlPiUgCiAgIyBmaWx0ZXIoZGF0ZSA+PSBhcy5EYXRlKCcyMDE4LTA2LTAxJykgJiBkYXRlIDw9IGFzLkRhdGUoJzIwMTgtMDctMDEnKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGltZV9ociwgeSA9IGtfd2luZCwgZ3JvdXAgPSBkYXRlKSkgKwogIGdlb21fbGluZShhZXMoY29sID0gZGF0ZSkpICsKICAjIGZhY2V0X3dyYXAofiBsdWJyaWRhdGU6Om1vbnRoKGRhdGUpKSArCiAgIyBmYWNldF93cmFwKH4gbHVicmlkYXRlOjp5ZGF5KGRhdGUpKSArCiAgIyBmYWNldF93cmFwKH4gbHVicmlkYXRlOjp3ZGF5KGRhdGUsIFRSVUUpKSArCiAgeGxpbShjKDAsIDI0KSkgKwogIHRoZW1lX2J3KCkKYGBgCgpgYGB7cn0Kd2luZF9kZiAlPiUKICBtdXRhdGUoZGF0ZSA9IGx1YnJpZGF0ZTo6ZGF0ZShkYXRldGltZSkpICU+JQogIG11dGF0ZSh0aW1lX2hyID0gbHVicmlkYXRlOjpob3VyKGRhdGV0aW1lKSkgJT4lIAogIG11dGF0ZSh3aW5kX3RocmVzaCA9IHdzX21zID4gMC43KSAlPiUKICAjIGZpbHRlcihkYXRlID49IGFzLkRhdGUoJzIwMTgtMDYtMDEnKSAmIGRhdGUgPD0gYXMuRGF0ZSgnMjAxOC0wNy0wMScpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXRldGltZSwgeSA9IGtfd2luZCwgZ3JvdXAgPSBkYXRlKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbCA9IHdpbmRfdGhyZXNoKSwgc2l6ZSA9IDAuNSkgKwogICMgZmFjZXRfd3JhcCh+IGx1YnJpZGF0ZTo6bW9udGgoZGF0ZSkpICsKICAjIGZhY2V0X3dyYXAofiBsdWJyaWRhdGU6OnlkYXkoZGF0ZSkpICsKICAjIGZhY2V0X3dyYXAofiBsdWJyaWRhdGU6OndkYXkoZGF0ZSwgVFJVRSkpICsKICAjIHhsaW0oYygwLCAyNCkpICsKICB0aGVtZV9idygpCmBgYAoKIyMjIFdhdGVyIGRlcHRoCgpgYGB7cn0Kd2xfZGYgPC0gcmVhZF9jc3YoImRhdGEvd2F0ZXJsZXZlbF9xYi5jc3YiKQpgYGAKCiMjIyBDb21iaW5lIGRhdGEKCkNvbWJpbmUgMyBkYXRhIHNvdXJjZXMgaW50byBvbmUgZGF0YSBmcmFtZSAod2xfZGYsIHdpbmRfcWIsIHRlbXBfZGYpCgpgYGB7cn0KaGVhZCh3bF9kZikgIyB3YXRlciBsZXZlbCBpcyBkYWlseQpoZWFkKHdpbmRfZGYpICMgaG91cmx5IHdpbmQgc3BlZWQgc3RhcnRzIDYtMjcsIGluY2x1ZGVzIGsKaGVhZCh0ZW1wX2RmKSAjIGhvdXJseSB0ZW1wLCBzdGFydHMgNy0yMQpgYGAKCmBgYHtyfQp0YWlsKHRlbXBfZGYpICMgZW5kcyA5LTMwCnRhaWwod2luZF9kZikgIyBlbmRzIDktMzAKdGFpbCh3bF9kZikgIyBlbmRzIDktMDQKYGBgCmhvdXJseSB0aW1lIHNlcmllcyBvZiB3aW5kLCB3YXRlciBsZXZlbCwgdGVtcCBiZXR3ZWVuIDctMjEgYW5kIDktMDQKClJvbGxpbmcgbWVyZ2Ugd2l0aCBkYXRhLnRhYmxlIHBhY2thZ2UKCmBgYHtyfQp0ZW1wX2R0IDwtIHRlbXBfZGYgJT4lIAogIGRhdGEudGFibGUoKSAlPiUKICBzZXRrZXkoZGF0ZXRpbWUpCndpbmRfZHQgPC0gd2luZF9kZiAlPiUgCiAgZGF0YS50YWJsZSgpICU+JQogIHNldGtleShkYXRldGltZSkKCmtkYXRhIDwtIHRlbXBfZHRbd2luZF9kdCwgcm9sbCA9ICJuZWFyZXN0Il0KCgprZGF0YSA8LSBrZGF0YSAlPiUKICBtdXRhdGUoZGF0ZSA9IGx1YnJpZGF0ZTo6ZGF0ZShkYXRldGltZSkpICU+JSAKICBsZWZ0X2pvaW4oZHBseXI6OnNlbGVjdCh3bF9kZiwgLWRhdGV0aW1lKSkKYGBgCgpgYGB7cn0Kd3JpdGVfY3N2KGtkYXRhLCAiZGF0YS9rZGF0YS5jc3YiKQpgYGAKCiMgQXBwbHkgQ2FsY3VsYXRpb25zCgpNYWtlIGEgZnVuY3Rpb24gdGhhdCB3aWxsIHVzZSB0aGF0IGFzIGlucHV0IHRvIGNhbGN1bGF0ZSBhIG5ldyBjb2x1bW4gd2l0aCAkayQgdmFsdWVzLgoKMS4gQ2FsY3VsYXRlIGBkVGAgZnJvbSB0ZW1wZXJhdHVyZSBjb2x1bW4KMS4gQWRkIGB0ZW1wX3RocmVzaGAgKGlmIGB0ZW1wX0NgIDwgNCkKMS4gQ2FsY3VsYXRlIGBxYCAoaGVhdCBmbHV4KSBhbmQgYHFfbmVnYCAoaWYgJHEgPCAwJCkKMS4gQ2FsY3VsYXRlIGBSYWAgYW5kIGBSYV90aHJlc2hgIChpZiAkUmEgPiA4XHRpbWVzIDEwXjYkKQoxLiBEZXRlcm1pbmUgYGtfY2F0ZWdvcnlgICh3aW5kIG9yIHRoZXJtYWwpLCBpZiBjb25kaXRpb25zIGZvciAka197dGhlcm1hbH0kIGFyZSBtZXQ6IGBxX25lZyA9IFRSVUVgLCBgUmFfdGhyZXNoID0gVFJVRWAsIG9yIGB0ZW1wX3RocmVzaCA9IFRSVUVgLiAKMS4gRm9yIHJvd3Mgd2hlcmUgYGtfY2F0ZWdvcnkgPT0gIndpbmQiYCwgY2FsY3VsYXRlIGBrX2NtaHJgIHVzaW5nIGBjYWxjX2tfcG9pbmRleHRlcjJhKClgLiAKMS4gRm9yIHJvd3Mgd2hlcmUgYGtfY2F0ZWdvcnkgPT0gInRoZXJtYWwiYCwgY2FsY3VsYXRlIGBrX2NtaHJgIHVzaW5nIGBjYWxjX2tfcG9pbmRleHRlcjJiKClgLgoKQ2FsY3VsYXRlIHRpbWUgc2VyaWVzIG9mICRxJCBzdXJmYWNlIGhlYXQgZmx1eCAoJFdtXnstMn0kKSBhcyBhIGZ1bmN0aW9uIG9mIHRlbXBlcmF0dXJlIHRpbWUgc2VyaWVzIGFuZCB3YXRlciBjb2x1bW4gZGVwdGgKCiogJFxmcmFje2RUX2J9e2R0fSQgaW4gJFxmcmFje0t9e3NlY30kIHdpbGwgbmVlZCB0byBjb252ZXJ0IGZyb20gJFxmcmFje0N9e2hyfSQKCgpgYGB7cn0Ka2RmIDwtIGtkYXRhICU+JSAKICBmaWx0ZXIoIWlzLm5hKHdsX20pKSAlPiUKICAjIG11dGF0ZShxX25lZyA9IHFfd20yIDwwKSAlPiUKICBtdXRhdGUodGVtcF90aHJlc2ggPSB0ZW1wX0MgPCA0KQpgYGAKCmBgYHtyfQpoZWFkKGtkZikKYGBgCkNyb3AgdG8ganVzdCBKdWx5IDI0IC0gQXVndXN0IDI0CgpgYGB7cn0Ka2RmIDwtIGtkZiAlPiUgCiAgZHBseXI6OmZpbHRlcihkYXRlID49IGFzLkRhdGUoJzIwMTgtMDctMjMnKSAmIGRhdGUgPD0gYXMuRGF0ZSgnMjAxOC0wOC0yNCcpKQpgYGAKCmBgYHtyfQprZGYgJT4lIAogIGRwbHlyOjpzZWxlY3QoLWRhdGUsIC10ZW1wX3RocmVzaCwgLWtfd2luZCkgJT4lCiAgdGlkeXI6OmdhdGhlcih2YXJpYWJsZSwgdmFsdWUsIHRlbXBfQzp3bF9tKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXRldGltZSwgeSA9IHZhbHVlKSkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF93cmFwKHZhcnModmFyaWFibGUpLCBzY2FsZXMgPSAiZnJlZV95IiwgbmNvbCA9IDEpICsKICB0aGVtZV9idygpCmBgYAoKSGVhdCBmbHV4CgpgYGB7cn0Ka2RmJGR0ZW1wIDwtIGMoTkEsIGRpZmYoa2RmJHRlbXBfQykpICMgcmV2aXNpdCBmb3Igc21vb3RoaW5nCmtkZiAlPiUKICAjIHNsaWNlKC0xKSAlPiUgCiAgbXV0YXRlKGR0X3BvcyA9IGR0ZW1wPjApICU+JQogIGdncGxvdChhZXMoeCA9IGRhdGV0aW1lLCB5ID0gdGVtcF9DKSkgKwogIGdlb21fbGluZShjb2wgPSAiZ3JheSIpICsKICBnZW9tX3BvaW50KGFlcyhjb2wgPSBkdF9wb3MpKSArIHRoZW1lX2J3KCkKYGBgCgpgYGB7cn0Ka2RmJHFfd20yIDwtIHBtYXBfZGJsKGxpc3QodGVtcF9DID0ga2RmJHRlbXBfQywKICAgICAgICAgICAgICB3YXRlcmRlcHRoX20gPSBrZGYkd2xfbSwKICAgICAgICAgICAgICBkVCA9IGtkZiRkdGVtcCksCiAgICAgICAgICAgICAgY2FsY19xX2hlYXRmbHV4KQoKYGBgCgpgYGB7cn0Ka2RmICU+JQogIG11dGF0ZShkdF9wb3MgPSBkdGVtcD4wKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXRldGltZSwgeSA9IHFfd20yKSkgKwogIGdlb21fbGluZShjb2wgPSAiZ3JheSIpICsKICBnZW9tX3BvaW50KGFlcyhjb2wgPSBkdF9wb3MpKSArIHRoZW1lX2J3KCkKYGBgCgpgYGB7cn0KIyBrZGYkUmEgPC0ga2RmICU+JSBwbWFwX2RibChjYWxjX3JheWxlaWdoKCkpCmtkZiRSYSA8LSBwbWFwX2RibChsaXN0KHEgPSBrZGYkcV93bTIsIAogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wX0MgPSBrZGYkdGVtcF9DLCAKICAgICAgICAgICAgICAgICAgICAgICAgbHNjYWxlID0ga2RmJHdsX20pLCAKICAgICAgICAgICAgICAgICAgIGNhbGNfcmF5bGVpZ2gpCmBgYAoKYGBge3J9CmtkZiRSYV90aHJlc2ggPC0ga2RmJFJhID4gOGU2CmBgYAoKYGBge3J9CmtkZiAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXRldGltZSwgeSA9IFJhKSkgKwogIGdlb21fbGluZShjb2wgPSAiZ3JheSIpICsKICBnZW9tX3BvaW50KGFlcyhjb2wgPSBSYV90aHJlc2gpKSArIHRoZW1lX2J3KCkKYGBgCgpgYGB7cn0Ka2RmJGtfY2F0ZWdvcnkgPC0gTkEKa2RmIDwta2RmICU+JQogIG11dGF0ZShxX3BvcyA9IHFfd20yID49MCkgJT4lIAogIG11dGF0ZShrX2NhdGVnb3J5ID0gZHBseXI6OmNhc2Vfd2hlbigKICAgIHFfcG9zIH4gIndpbmQiLAogICAgKHFfd20yIDwgMCB8IFJhX3RocmVzaCA8IDhlNikgfiAidGhlcm1hbCIKICApKQpgYGAKCgoKYGBge3J9CmtkZl90aGVybWFsIDwtIGtkZiAlPiUgZHBseXI6OmZpbHRlcihrX2NhdGVnb3J5ID09ICJ0aGVybWFsIikKCmtkZl90aGVybWFsJGtfdGhlcm1hbCA8LSBwdXJycjo6cG1hcF9kYmwobGlzdChxID0ga2RmX3RoZXJtYWwkcV93bTIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcF9DID0ga2RmX3RoZXJtYWwkdGVtcF9DKSwKICAgICAgICAgICAgICAgICAgIGNhbGNfa19wb2luZGV4dGVyMmIpCmBgYAoKYGBge3J9CmhlYWQoa2RmX3RoZXJtYWwpCgprZGZfam9pbiA8LSBrZGYgJT4lIGxlZnRfam9pbigKICBkcGx5cjo6c2VsZWN0KGtkZl90aGVybWFsLCBkYXRldGltZSwga190aGVybWFsKQopCmtkZl9qb2luIDwtIGtkZl9qb2luICU+JQogIG11dGF0ZShrX21peCA9IGRwbHlyOjpjYXNlX3doZW4oCiAgICBrX2NhdGVnb3J5ID09ICJ3aW5kIiB+IGtfd2luZCwKICAgIGtfY2F0ZWdvcnkgPT0gInRoZXJtYWwiIH4ga190aGVybWFsCiAgKSkKYGBgCgpgYGB7cn0Ka2RmX2pvaW4gJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZXRpbWUsIHkgPSBrX21peCkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludChhZXMoY29sID0ga19jYXRlZ29yeSkpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKwogIGZhY2V0X3dyYXAofiBsdWJyaWRhdGU6OndlZWsoZGF0ZSksIHNjYWxlcyA9ICJmcmVlX3giLCBuY29sID0gMSkgKwogICAgdGhlbWVfYncoKSArCiAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCgojIE5vdGVzCgoqKklkZWFzKioKCkNvbXBhcmUgbWV0aGFuZSBmbHV4IGFuZCBrIG1lYXN1cmVtZW50cyB3aXRoIGFuZCB3aXRob3V0IGNoYW5naW5nIHdhdGVyIGxldmVscyAtIHdoYXQgaXMgdGhlIGVmZmVjdCBvZiBpbmNsdWRpbmcgY2hhbmdpbmcgd2F0ZXIgbGV2ZWw/IHdoYXQgaXMgdGhlIHJlbGF0aXZlIGltcG9ydGFuY2Ugb2YgYSkgY2hhbmdpbmcgYXJlYWwgZXh0ZW50IG9mIHdhdGVyIHN1cmZhY2UgdG8gc2NhbGUgZmx1eCBieT8gYikgY2hhbmdlIGluIGsgdmFsdWUgYW5kIGsgY2F0ZWdvcnkgb24gdGhlIG1hZ25pdHVkZSBvZiB0aGUgZmx1eD8gYykgZGlsdXRpb24gZWZmZWN0IG9mIHRoZSBtZXRoYW5lIGNvbmNlbnRyYXRpb24gaW4gdGhlIHdhdGVyPwoKCgpTdXJmYWNlIGhlYXQgZmx1eCBhcHByb2FjaCBpbiBSZWFkIGV0IGFsLiAyMDEyIGFzc3VtZXMgdGhhdCBzZWRpbWVudCBoZWF0aW5nLCBhZHZlY3RlZCBjb21wb25lbnRzLCBhbmQgY2hhbmdlcyBpbiB3YXRlciBsZXZlbHMgYXJlIG5lZ2xpZ2libGUuIFRoZXNlIGFzc3VtcHRpb25zIGRvIG5vdCBob2xkIGluIGRlbG1hcnZhIGJheSB3ZXRsYW5kIHN5c3RlbXMhIAoKRGVsbWFydmEgYmF5IHdldGxhbmQgc2l0ZXMgYXJlIHNoZWx0ZXJlZCBieSB0cmVlIGNhbm9weSB3aGljaCBhZmZlY3RzIHRoZSB3aW5kIHNoZWFyIGRyaXZlbiBnYXMgZXhjaGFuZ2UuIFJlYWQgZXQgYWwuIG1ldGhvZCB1c2luZyBhcHByb2FjaCBvZiBzY2FsaW5nIHRoZSBlZmZlY3Qgb2Ygd2luZCBzaGVsdGVyaW5nIHdoZXJlIHRoZSBzaXplIG9mIHRoZSBsYWtlIGlzIHNtYWxsIGVub3VnaCwgc28gayBpcyByZWR1Y2VkIGZvciBhcmVhIGFmZmVjdGVkIGJ5IHNoZWx0ZXJpbmcgYXMgYSBmdW5jdGlvbiBvZiBkaXN0YW5jZSBmcm9tIHRyZWUgY2Fub3B5LiBVbmxpa2UgdGhhdCBtZXRob2QsIHRoZXJlIGlzIG5vIHdhdGVyIHN1cmZhY2UgYXJlYSB0aGF0IGlzIHVuYWZmZWN0ZWQgYnkgZWZmZWN0cyBvZiBjYW5vcHkgc2hlbHRlcmluZy4gQ2Fub3B5IGhlaWdodCBtZWFzdXJlbWVudHMgZnJvbSBEdWJheWFoIGV0IGFsLiBDTVMgcHJvZHVjdC4gCgpJbi1jYW5vcHkgd2luZCBzcGVlZCBpcyBjYWxjdWxhdGVkIGluIFBvaW5kZXh0ZXIgZXQgYWwuIG1ldGhvZCwgYXMgYSBmdW5jdGlvbiBvZiB3aW5kIHNwZWVkIG1lYXN1cmVkIGF0IDEwbS4gCgpPdXIgbWVhc3VyZW1lbnRzIG9mIHdpbmQgc3BlZWQgY2FuIGJlIHVzZWQgdG8gZXZhbHVhdGUgdGhlIG90aGVyIG1ldGhvZHMsIGJ5IGNvbXBhcmluZyBtZWFzdXJlZCBpbi1jYW5vcHkgd2luZCBzcGVlZCB0byB3aW5kIHNwZWVkIGZyb20gYSBuZWFyYnkgd2VhdGhlciBzdGF0aW9uIChtZWFzdXJlZCBhYm92ZSB0aGUgY2Fub3B5KS4gTmVlZCB0byBmaW5kIGEgbG9jYWwgd2VhdGhlciBzdGF0aW9uIHRvIGRvIHRoYXQ/IAoKTmVlZCB0byB1bmRlcnN0YW5kIHdoYXQgdGhlIGVuaGFuY2VtZW50IGZhY3RvciBpcyBhbGwgYWJvdXQgLSBjYW4gSSBqdXN0IHVzZSAkayA9IFxsYW5nbGUgVV97Y2Fub3B5fVxyYW5nbGVeMihcZnJhY3tTY317NjAwfSleey1ufSQgLSBhZGRpdGlvbmFsIGZhY3RvciBiZXlvbmQgbWVhbiB3aW5kIHNwZWVkIHRvIGNoYXJhY3Rlcml6ZSBlZmZlY3Qgb2Ygd2luZCBvbiAkayQgYmVjYXVzZSB0aGUgbGFyZ2VzdCBzY2FsZSBlZGRpZXMgaW4gdGhlIGNhbm9weSB3aW5kIGZpZWxkIGFyZSBoaWdobHkgaW50ZXJtaXR0ZW50LiBQb2luZGV4dGVyIGFuZCBWYXJpYW5vIDIwMTMgZ2l2ZSBhIHJlbGF0aW9uc2hpcCBmb3IgdGhlICRrX3s2MDB9JCBlbmhhbmNlbWVudCBmYWN0b3IgYXMgYSBmdWNudGlvbiBvZiAkXGZyYWN7XGxhbmdsZShVX3tjYW5vcHl9LVxsYW5nbGUgVV97Y2Fub3B5fVxyYW5nbGUpXjJccmFuZ2xlXntcZnJhY3sxfXsyfX19e1xsYW5nbGUgVV97Y2Fub3B5fVxyYW5nbGV9JC4gVGhlIGVmZmVjdCBvZiB0aGUgZ3VzdHMgaXMgaW50ZXJhY3Rpb25zIGJldHdlZW4gdGhlIHdpbmQgYW5kIHBsYW50IGNhbm9weSB0aGF0IGdlbmVyYXRlcyBpbnRlcm1pdHRlbnQsIGxhcmdlLXNjYWxlIGVkZGllcywgd2hpY2ggcHJlc3VtYWJseSBhcmUgdGhlIGd1c3RzIHRoYXQgZW5oYW5jZSBnYXMgZXhjaGFuZ2UgaW4gbmF0dXJhbCB3ZXRsYW5kcy4KCkNvbXBhcmUgd2luZCBndXN0IHNwZWVlZHMgYW5kIHdpbmQgc3BlZWRzIGZyb20gc29uaWMgYW5lbW9tZXRlciBtZWFzdXJlbWVudHMgdG8gaGVscCB0aGluayBhYm91dCB0aGlzLiAKCmBgYHtyfQpndXN0cyA8LSByZWFkX2NzdigiZGF0YS93aW5kZ3VzdHNfcWIuY3N2IikKYGBgCgpgYGB7cn0KZ3VzdHMgJT4lIAogIG11dGF0ZShkYXRlID0gbHVicmlkYXRlOjpkYXRlKGRhdGV0aW1lKSkgJT4lCiAgbXV0YXRlKHRpbWVfaHIgPSBsdWJyaWRhdGU6OmhvdXIoZGF0ZXRpbWUpKSAlPiUgCiAgIyBmaWx0ZXIoZGF0ZSA+PSBhcy5EYXRlKCcyMDE4LTA2LTAxJykgJiBkYXRlIDw9IGFzLkRhdGUoJzIwMTgtMDctMDEnKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGltZV9ociwgeSA9IGd1c3RzX21zLCBncm91cCA9IGRhdGUpKSArCiAgZ2VvbV9saW5lKGFlcyhjb2wgPSBkYXRlKSkgKwogICMgZmFjZXRfd3JhcCh+IGx1YnJpZGF0ZTo6bW9udGgoZGF0ZSkpICsKICAjIGZhY2V0X3dyYXAofiBsdWJyaWRhdGU6OnlkYXkoZGF0ZSkpICsKICAjIGZhY2V0X3dyYXAofiBsdWJyaWRhdGU6OndkYXkoZGF0ZSwgVFJVRSkpICsKICB4bGltKGMoMCwgMjQpKSArCiAgdGhlbWVfYncoKQpgYGAKCioqT3RoZXIgcmVsZXZhbnQgc3R1ZGllcyoqCgoqIEdvZHdpbiBldCBhbC4gMjAxMyBKR1IgRXZlbmluZyBtZXRoYW5lIGVtaXNzaW9uIGV2ZW50cyAtIGZvdW5kIHRoYXQgdGltaW5nIG9mIG5pZ2h0dGltZSBlbWlzc2lvbiBldmVudHMgKGFzIG1lYXN1cmVkIGJ5IGZsdXggdG93ZXJzKSBjb2luY2lkZWQgd2l0aCBjb29saW5nIGFuZCBjb252ZWN0aXZlIG1peGluZyB3aXRoaW4gaG9sbG93cywgd2hpY2ggb2NjdXJyZWQgcmVndWxhcmx5IGR1cmluZyB0aGUgZ3Jvd2luZyBzZWFzb24uIFRoZXkgcHJvcG9zZSB0aGF0IGRpdXJuYWwgdGhlcm1hbCBzdHJhdGlmaWNhdGlvbiBpbiBzaGFsbG93IHBvb2xzIHRyYXBzIG1ldGhhbmUgYnkgbGltaXRpbmcgdHVyYnVsZW50IHRyYW5zcG9ydCwgYW5kIHRoaXMgbWV0aGFuZSBzdG9yZWQgZHVyaW5nIGRheXRpbWUgaGVhdGluZyBpcyBsYXRlciByZWxlYXNlZCBkdXJpbmcgZXZlbmluZyBjb29saW5nIGR1ZSB0byBjb252ZWN0aXZlIHR1cmJ1bGVudCBtaXhpbmcuIAoqIEhhcHBlbGwgZXQgYWwuIDE5OTUgdXNlZCBmbG9hdGluZyBjaGFtYmVyIG1lYXN1cmVtZW50cyBpbiBhIEZsb3JpZGEgaGFyZHdvb2Qgc3dhbXAgYW5kIGZvdW5kICRrX3s2MDB9JCB2YWx1ZXMgYXZlcmFnZWQgJDAuNzhccG0gMC41NCBjbSBoXnstMX0kCiogVmFyaWFubyBldCBhbC4gMjAwOSAtICRTRl82JCB0cmFjZXIgcmVsZWFzZWQgaW4gdGhlIHBhdHRlcm5lZCBtYXJzaGVzIG9mIHRoZSBGbG9yaWRhIEV2ZXJnbGFkZXMgaW5kaWNhdGVkICRrX3s2MDB9JCB0aGVyZSByYW5nZWQgZnJvbSAwLjMgdG8gMS44IGNtIGheLTEKKiBTZWJhY2hlciBldCBhbC4gMTk4MyBtZWFzdXJlZCBnYXMgZXhjaGFuZ2UgaW4gYSB3ZXRsYW5kIHBvbmQgZnJlZSBvZiBlbWVyZ2VudCB2ZWdldGF0aW9uIGFuZCB3aW5kIHNwZWVkIDIgY20gYWJvdmUgdGhlIHdhdGVyIHN1cmZhY2UsIHdpbmQgc3BlZWQgYXJvdW5kIDAuOCBtIHNeLTEuIAoKCg==